// Copyright (c) 2022 NetEase, Inc. All rights reserved.
// Use of this source code is governed by a MIT license that can be
// found in the LICENSE file.

import 'dart:convert';

import 'package:hawk/hawk.dart';
import 'package:nim_core/nim_core.dart';

import '../main_test.dart';
import 'method_name_value.dart';

/// 配置case用例地址： https://g.hz.netease.com/yunxin-app/kit_automation_test/-/tree/release/integration_case
/// case模板，模板代码的class需要在 [nim_core_test.dart] 中注册。
/// 执行结果通过返回[handleCaseResult] ,做期望值匹配
/// 执行方式,请不要在本地执行：在packages/nim_core/nim_core/example目录下
/// flutter drive --driver=test_driver/integration_test.dart --target=integration_test/main_test.dart  --keep-app-running
class HandleSuperTeamCase extends HandleBaseCase {
  HandleSuperTeamCase();

  @override
  Future<ResultBean?> handle(event) async {
    super.handle(event);

    if (className?.trim() != 'SuperTeamService') {
      return null;
    }

    var inputParams = Map<String, dynamic>();
    if (params != null && params!.length > 0) {
      inputParams = params![0] as Map<String, dynamic>;
    }

    switch (methodName) {
      case onMemberUpdate:
        subsriptions.add(
            NimCore.instance.superTeamService.onMemberUpdate.listen((event) {
          print('SuperTeamService#onMemberUpdate event : $event');
          IntegratedManager.instance.report('onMemberUpdate',
              ResultBean(code: 0, data: event.map((e) => e.toMap()).toList()));
        }));
        handleCaseResult = ResultBean.success(data: null);
        break;
      case onMemberRemove:
        subsriptions.add(
            NimCore.instance.superTeamService.onMemberRemove.listen((event) {
          print('SuperTeamService#onMemberRemove event : $event');
          IntegratedManager.instance.report('onMemberRemove',
              ResultBean(code: 0, data: event.map((e) => e.toMap()).toList()));
        }));
        handleCaseResult = ResultBean.success(data: null);
        break;
      case onSuperTeamUpdate:
        subsriptions.add(
            NimCore.instance.superTeamService.onSuperTeamUpdate.listen((event) {
          print('SuperTeamService#onSuperTeamUpdate event : $event');
          IntegratedManager.instance.report('onSuperTeamUpdate',
              ResultBean(code: 0, data: event.map((e) => e.toMap()).toList()));
        }));
        handleCaseResult = ResultBean.success(data: null);
        break;
      case onSuperTeamRemove:
        subsriptions.add(
            NimCore.instance.superTeamService.onSuperTeamRemove.listen((event) {
          print('SuperTeamService#onSuperTeamRemove event : $event');
          IntegratedManager.instance.report(
              'onSuperTeamRemove', ResultBean(code: 0, data: event.toMap()));
        }));
        handleCaseResult = ResultBean.success(data: null);
        break;
      case queryTeamList:
        final result = await NimCore.instance.superTeamService.queryTeamList();
        handleCaseResult = ResultBean(
            code: result.code,
            message: methodName,
            data: result.data?.map((e) => e.toMap()).toList());
        break;
      case queryTeamListById:
        final result = await NimCore.instance.superTeamService
            .queryTeamListById(covertJsonToListStr(inputParams['idList']));
        handleCaseResult = ResultBean(
            code: result.code,
            message: methodName,
            data: result.data?.map((e) => e.toMap()).toList());
        break;
      case queryTeam:
        final result = await NimCore.instance.superTeamService
            .queryTeam(inputParams['teamId']);
        handleCaseResult = ResultBean(
            code: result.code, message: methodName, data: result.data?.toMap());
        break;
      case searchTeam:
        final result = await NimCore.instance.superTeamService
            .searchTeam(inputParams['teamId']);
        handleCaseResult = ResultBean(
            code: result.code, message: methodName, data: result.data?.toMap());
        break;
      case applyJoinTeam:
        final result = await NimCore.instance.superTeamService
            .applyJoinTeam(inputParams['teamId'], inputParams['postscript']);
        handleCaseResult = ResultBean(
            code: result.code, message: methodName, data: result.data?.toMap());
        break;
      case passApply:
        final result = await NimCore.instance.superTeamService.passApply(
          inputParams['teamId'],
          inputParams['account'],
        );
        handleCaseResult = ResultBean(
            code: result.code, message: methodName, data: result.toMap());
        break;
      case rejectApply:
        final result = await NimCore.instance.superTeamService.rejectApply(
          inputParams['teamId'],
          inputParams['account'],
          inputParams['reason'],
        );
        handleCaseResult = ResultBean(
            code: result.code, message: methodName, data: result.toMap());
        break;
      case addMembers:
        final result = await NimCore.instance.superTeamService.addMembers(
          inputParams['teamId'],
          covertJsonToListStr(inputParams['accountList']),
          inputParams['msg'],
        );
        handleCaseResult = ResultBean(
            code: result.code,
            message: methodName,
            data: result.data?.toList());
        break;
      case acceptInvite:
        final result = await NimCore.instance.superTeamService.acceptInvite(
          inputParams['teamId'],
          inputParams['inviter'],
        );
        handleCaseResult = ResultBean(
            code: result.code, message: methodName, data: result.toMap());
        break;
      case declineInvite:
        final result = await NimCore.instance.superTeamService.declineInvite(
          inputParams['teamId'],
          inputParams['inviter'],
          inputParams['reason'],
        );
        handleCaseResult = ResultBean(
            code: result.code, message: methodName, data: result.toMap());
        break;
      case removeMembers:
        final result = await NimCore.instance.superTeamService.removeMembers(
          inputParams['teamId'],
          covertJsonToListStr(inputParams['members']),
        );
        handleCaseResult = ResultBean(
            code: result.code, message: methodName, data: result.toMap());
        break;
      case quitTeam:
        final result = await NimCore.instance.superTeamService.quitTeam(
          inputParams['teamId'],
        );
        handleCaseResult = ResultBean(
            code: result.code, message: methodName, data: result.toMap());
        break;
      case queryMemberList:
        final result = await NimCore.instance.superTeamService.queryMemberList(
          inputParams['teamId'],
        );
        handleCaseResult = ResultBean(
            code: result.code,
            message: methodName,
            data: result.data?.map((e) => e.toMap()).toList());
        break;
      case queryTeamMember:
        final result = await NimCore.instance.superTeamService.queryTeamMember(
          inputParams['teamId'],
          inputParams['account'],
        );
        handleCaseResult = ResultBean(
            code: result.code, message: methodName, data: result.data?.toMap());
        break;
      case queryMemberListByPage:
        final result =
            await NimCore.instance.superTeamService.queryMemberListByPage(
          inputParams['teamId'],
          inputParams['offset'],
          inputParams['limit'],
        );
        handleCaseResult = ResultBean(
            code: result.code,
            message: methodName,
            data: result.data?.map((e) => e.toMap()).toList());
        break;
      case updateMemberNick:
        final result = await NimCore.instance.superTeamService.updateMemberNick(
          inputParams['teamId'],
          inputParams['account'],
          inputParams['nick'],
        );
        handleCaseResult = ResultBean(
            code: result.code, message: methodName, data: result.toMap());
        break;
      case updateMyTeamNick:
        final result = await NimCore.instance.superTeamService.updateMyTeamNick(
          inputParams['teamId'],
          inputParams['nick'],
        );
        handleCaseResult = ResultBean(
            code: result.code, message: methodName, data: result.toMap());
        break;
      case updateMyMemberExtension:
        final result =
            await NimCore.instance.superTeamService.updateMyMemberExtension(
          inputParams['teamId'],
          (inputParams['extension'] as Map).cast<String, Object>(),
        );
        handleCaseResult = ResultBean(
            code: result.code, message: methodName, data: result.toMap());
        break;
      case transferTeam:
        final result = await NimCore.instance.superTeamService.transferTeam(
          inputParams['teamId'],
          inputParams['account'],
          inputParams['quit'],
        );
        handleCaseResult = ResultBean(
            code: result.code,
            message: methodName,
            data: result.data?.map((e) => e.toMap()).toList());
        break;
      case addManagers:
        final result = await NimCore.instance.superTeamService.addManagers(
          inputParams['teamId'],
          covertJsonToListStr(inputParams['accountList']),
        );
        handleCaseResult = ResultBean(
            code: result.code,
            message: methodName,
            data: result.data?.map((e) => e.toMap()).toList());
        break;
      case removeManagers:
        final result = await NimCore.instance.superTeamService.removeManagers(
          inputParams['teamId'],
          covertJsonToListStr(inputParams['accountList']),
        );
        handleCaseResult = ResultBean(
            code: result.code,
            message: methodName,
            data: result.data?.map((e) => e.toMap()).toList());
        break;
      case muteTeamMember:
        final result = await NimCore.instance.superTeamService.muteTeamMember(
          inputParams['teamId'],
          covertJsonToListStr(inputParams['accountList']),
          inputParams['mute'],
        );
        handleCaseResult = ResultBean(
            code: result.code, message: methodName, data: result.toMap());
        break;
      case muteAllTeamMember:
        final result =
            await NimCore.instance.superTeamService.muteAllTeamMember(
          inputParams['teamId'],
          inputParams['mute'],
        );
        handleCaseResult = ResultBean(
            code: result.code, message: methodName, data: result.toMap());
        break;
      case queryMutedTeamMembers:
        final result =
            await NimCore.instance.superTeamService.queryMutedTeamMembers(
          inputParams['teamId'],
        );
        handleCaseResult = ResultBean(
            code: result.code,
            message: methodName,
            data: result.data?.map((e) => e.toMap()).toList());
        break;
      case updateTeamFields:
        NIMTeamUpdateFieldRequest request = NIMTeamUpdateFieldRequest();
        var requestJson = (inputParams['request'] as Map).map(
            (key, value) => MapEntry<String, Object>(key.toString(), value));
        if (requestJson["announcement"] != null) {
          request.setAnnouncement(requestJson["announcement"] as String?);
        }
        if (requestJson["extension"] != null) {
          request.setExtension(requestJson["extension"] as String?);
        }
        if (requestJson["icon"] != null) {
          request.setIcon(requestJson["icon"] as String?);
        }
        if (requestJson["introduce"] != null) {
          request.setIntroduce(requestJson["introduce"] as String?);
        }
        if (requestJson["name"] != null) {
          request.setName(requestJson["name"] as String?);
        }
        if (requestJson["beInviteMode"] != null) {
          request.setBeInviteMode(NIMTeamBeInviteModeEnumConverter()
              .fromValue(requestJson["beInviteMode"] as String));
        }
        if (requestJson["inviteMode"] != null) {
          request.setInviteMode(NIMTeamInviteModeEnumConverter()
              .fromValue(requestJson["inviteMode"] as String));
        }
        if (requestJson["maxMemberCount"] != null) {
          request.setMaxMemberCount(requestJson["maxMemberCount"] as int);
        }
        if (requestJson["teamExtensionUpdateMode"] != null) {
          request.setTeamExtensionUpdateMode(
              NIMTeamExtensionUpdateModeEnumConverter()
                  .fromValue(requestJson["teamExtensionUpdateMode"] as String));
        }
        if (requestJson["teamUpdateMode"] != null) {
          request.setTeamUpdateMode(NIMTeamUpdateModeEnumConverter()
              .fromValue(requestJson["teamUpdateMode"] as String));
        }
        if (requestJson["verifyType"] != null) {
          request.setVerifyType(NIMVerifyTypeEnumConverter()
              .fromValue(requestJson["verifyType"] as String));
        }
        final result = await NimCore.instance.superTeamService.updateTeamFields(
          inputParams['teamId'],
          request,
        );
        handleCaseResult = ResultBean(
            code: result.code, message: methodName, data: result.toMap());
        break;
      case muteTeam:
        final result = await NimCore.instance.superTeamService.muteTeam(
          inputParams['teamId'],
          enumDecodeNullable(NIMTeamMessageNotifyTypeEnumEnumMap,
              inputParams['notifyType'] ?? 'all')!,
        );
        handleCaseResult = ResultBean(code: result.code, message: methodName);
        break;
      case searchTeamIdByName:
        final result =
            await NimCore.instance.superTeamService.searchTeamIdByName(
          inputParams['name'],
        );
        handleCaseResult = ResultBean(
            code: result.code,
            message: methodName,
            data: result.data?.toList());
        break;
      case searchTeamsByKeyword:
        final result =
            await NimCore.instance.superTeamService.searchTeamsByKeyword(
          inputParams['keyword'],
        );
        handleCaseResult = ResultBean(
            code: result.code,
            message: methodName,
            data: result.data?.map((e) => e.toMap()).toList());
        break;
      default:
        return null;
    }
    return handleCaseResult;
  }

  /// [index] params index,
  /// [key] params key,
  List<String> covertJsonToList(int index, String key) {
    List<String> list = [];
    try {
      final paramsByIndex =
          (jsonDecode(params?[index]) as Map<String, dynamic>?)?[key];
      paramsByIndex?.forEach((element) => list.add(element));
    } on Exception catch (e) {
      print('=========>> index: $index, key: $key,e :$e');
    }
    return list;
  }
}

/// [json] inputParams jsonKey
/// covert jsonList to List<String>
List<String> covertJsonToListStr(dynamic json) {
  List jsonStr = json as List<dynamic>;
  return jsonStr.map((e) => e.toString()).toList();
}
